#!/usr/bin/env python
# ./testBulkRm.py <files> <se> <token>
import gfal
import lcg_util
import sys
import os
import re
import time

DEBUG = True

def printEntries(entries, lines):
    for f in entries:
        if not f.has_key('stat'):
            print '??????????', f['surl']
            continue
        
        mstring = '----------'
        mode = f['stat'][0]
        if mode & 256: 
            mstring = mstring[:1] + 'r' + mstring[2:]
        if mode & 128: 
            mstring = mstring[:2] + 'w' + mstring[3:] 
        if mode & 64:
            mstring = mstring[:3] + 'x' + mstring[4:] 
        if mode & 32:
            mstring = mstring[:4] + 'r' + mstring[5:]
        if mode & 16:
            mstring = mstring[:5] + 'w' + mstring[6:]
        if mode & 8:
            mstring = mstring[:6] + 'x' + mstring[7:]
        if mode & 4:
            mstring = mstring[:7] + 'r' + mstring[8:]
        if mode & 2:
            mstring = mstring[:8] + 'w' + mstring[9:]
        if mode & 1:
            mstring = mstring[:9] + 'x' + mstring[10:]
        
        print mstring,
        print f['stat'][3], # UID
        print f['stat'][4], # Group ID
        print f['stat'][5], # ???
        print f['stat'][6], # Size
        lines.append(f['surl'])
        if f.has_key('locality'):
            print f['locality'],
        else:
            print 'UNKNONW',
        print f['surl'] #, f['stat']
        if f.has_key('subpaths'):
            printEntries(f['subpaths'], lines)


def uploadFile(dest, token=''):
  cmd = "lcg-cr -T srmv2 -D srmv2 -b -v --vo atlas file:/etc/passwd "
  if len(token):
    cmd += '-s '+ token + ' '
  cmd += "-d '" + dest +"'"
  pipe = os.popen(cmd, 'r')
  lines = pipe.readlines()
  surl = ''
  guid = ''
  for line in lines:
      if line.find("Destination URL registered in Catalog:") == 0:
        surl = line.split()[5]
      if line.find('guid:') == 0:
        guid = line.rstrip('\n\r')
  if not len(surl) or not len(guid):
      print "lcg-cr failed"
      print "Command was", cmd
  else:
      if DEBUG:  print
      if DEBUG:  print "Upload successful: guid", guid, "surl", surl
  return (surl, guid)        


def srmRm(surls):
    (returncode, gfal_o, errmsg) = gfal.gfal_init({'surls': surls, 'defaultsetype': 'srmv2', 'setype': 'srmv2', 'no_bdii_check': 1})
    if returncode:
        print "gfal_init failed:", returncode, "Error:", errmsg
        return -1

    (returncode, gfal_o, errmsg) = gfal.gfal_deletesurls(gfal_o)
    if returncode:
        print "gfal_deletesurls failed:", returncode, "Error:", errmsg
        return -1

    (returncode, gfal_o, filestatuses) = gfal.gfal_get_results(gfal_o)
    if returncode == 0:
        print "gfal_deletesurls/get_results failed:", returncode, "Error:", errmsg  
        return -1
    
    print filestatuses
    gfal.gfal_internal_free(gfal_o)
    
    return 0

    
def unlinkFile(guid, surl):
    if DEBUG: print "Unlinking >" + surl +"< >" + guid +"<"
    (returncode, errmsg) = lcg_util.lcg_ufx (surl, guid, 'atlas','', 0)
    if errmsg != '':
        print "Unlinking file from LFC failed:", errmsg
        return -1
    return 0

def srmLs(paths, lines):
#    print "Doing ls on ", paths
    (returncode, gfal_o, errmsg) = gfal.gfal_init({'surls': paths, 'defaultsetype': 'srmv2', 'setype': 'srmv2', 'no_bdii_check': 1, 'srmv2_lslevels':1})
    if returncode:
        print "gfal_init failed:", returncode, "Error:", errmsg
        return returncode

    (returncode, gfal_o, errmsg) = gfal.gfal_ls(gfal_o)
    if returncode != 0:
        print "gfal_ls failed:", returncode, "Error:", errmsg
        return returncode
    
    (returncode, gfal_o, filestatuses) = gfal.gfal_get_results(gfal_o)
    if returncode == 0:
        print "gfal_get_results failed:", returncode, "Error:", errmsg  
        return -1

    printEntries(filestatuses, lines)

    gfal.gfal_internal_free(gfal_o)
    
    return 0

def getPending(listOfResults):
  pending = 0
  for result in listOfResults:
      if result['status'] == 0:
          if DEBUG: print "%s  PENDING" % result['surl']
          pending = 1
      elif result['status'] == 1:
          if DEBUG: print "%s  READY" % result['surl']
      elif result['status'] == -1:
          print "%s  ERROR" % result['surl']
          print "  => %s" % result['explanation']
          return -1
  return pending


def prestage(surls, token, pollTime=10, timeout = 3600):
    startTime = time.time()
    
    # Create the dictionary used by gfal
    gfalRequest = {}
    gfalRequest['surls'] = surls
    gfalRequest['nbfiles'] =  len(surls)
    gfalRequest['defaultsetype'] = 'srmv2'
    gfalRequest['no_bdii_check'] = 1
    gfalRequest['srmv2_spacetokendesc'] = token

    errCode,gfalObject,errMessage = gfal.gfal_init(gfalRequest)
    if not errCode == 0:
        print "Failed to initialise gfal_init: %s" % errMessage
        return -1

    errCode,gfalObject,errMessage = gfal.gfal_prestage(gfalObject)
    if not errCode == 0:
        print "Failed to perform gfal_prestage: %s" % errMessage
        return -1

    numberOfResults,gfalObject,listOfResults = gfal.gfal_get_results(gfalObject)
    if numberOfResults <= 0:
        print "Did not obtain results with gfal_get_results."
        return -1

    if DEBUG: print listOfResults
    pending = getPending(listOfResults)

    while pending > 0:
        if time.time() - startTime > timeout:
            print listOfResults
            return -1
        time.sleep(pollTime)
        errCode,gfalObject,errMessage = gfal.gfal_prestagestatus(gfalObject)
        if not errCode == 0:
            print "Failed to perform gfal_prestage: %s" % errMessage
            return -1

        numberOfResults,gfalObject,listOfResults = gfal.gfal_get_results(gfalObject)
        if numberOfResults <= 0:
            print "Did not obtain results with gfal_get_results."
            return -1

        if DEBUG: print listOfResults
        pending = getPending(listOfResults)

    if pending < 0:
        return -1
    
    return 0

def release(surls):
    # Create the dictionary used by gfal
    gfalRequest = {}
    gfalRequest['surls'] = surls
    gfalRequest['nbfiles'] =  len(surls)
    gfalRequest['defaultsetype'] = 'srmv2'
    gfalRequest['no_bdii_check'] = 1
                            
    errCode,gfalObject,errMessage = gfal.gfal_init(gfalRequest)
    if not errCode == 0:
        print "Failed to initialise gfal_init: %s" % errMessage
        return -1
                                                    
    errCode,gfalObject,errMessage = gfal.gfal_release(gfalObject)
    if not errCode == 0:
        print "Failed to perform gfal_release: %s" % errMessage
        return -1
                                                                            
    numberOfResults,gfalObject,listOfResults = gfal.gfal_get_results(gfalObject)
    if numberOfResults <= 0:
        print "Did not obtain results with gfal_get_results."
        return -1
                                                                                                    
    if DEBUG: print listOfResults
    pending = getPending(listOfResults)

    return pending

# The following does not work, as we cannot know any request tokens in this framework
def pin(surls):
    # Create the dictionary used by gfal
    gfalRequest = {}
    gfalRequest['surls'] = surls
    gfalRequest['nbfiles'] =  len(surls)
    gfalRequest['defaultsetype'] = 'srmv2'
    gfalRequest['no_bdii_check'] = 1
                                                    
    errCode,gfalObject,errMessage = gfal.gfal_init(gfalRequest)
    if not errCode == 0:
        print "Failed to initialise gfal_init: %s" % errMessage
        return -1
                                                                                             
    errCode,gfalObject,errMessage = gfal.gfal_pin(gfalObject)
    if not errCode == 0:
        print "Failed to perform gfal_pin: %s" % errMessage
        return -1
                                                                                                                                      
    numberOfResults,gfalObject,listOfResults = gfal.gfal_get_results(gfalObject)
    if numberOfResults <= 0:
        print "Did not obtain results with gfal_get_results."
        return -1
                                                                                                                                                                               
    if DEBUG: print listOfResults    
    pending = getPending(listOfResults)

    return pending

def log(message):
    """print a message to the screen with a timestamp"""
    message = '[%s] %s' % (time.asctime(), message)
    print message
    

def fix_v2_surl(entriestodelete,srmaddon):
    """
    put missing string with port number and manager into every surl
    """
    surl,surls=[],[]
    for j in entriestodelete:
        tmp = entriestodelete[j]['surl'][0]
        if type(tmp) ==  list:
            surls.extend(tmp)
        else:
            surls.append(tmp)
    for j in surls:
        tmp2 = j.split('/')
        tmp2.insert(3,srmaddon)
        surl.append('/'.join(tmp2[0:3])+'/'.join(tmp2[3:]))
    return surl

                
